package com.keepitsimple.core;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

public class BeanUtils<T> {

	private static Map<Class<?>, Class<?>> classMap = new HashMap<Class<?>, Class<?>>();
	static
	{
		classMap.put(int.class, Integer.class);
		classMap.put(short.class, Short.class);
		classMap.put(long.class, Long.class);
		classMap.put(float.class, Float.class);
		classMap.put(double.class, Double.class);
		classMap.put(char.class, Character.class);
		classMap.put(boolean.class, Boolean.class);
		classMap.put(byte.class, Byte.class);
		classMap.put(Integer.class, Integer.class);
		classMap.put(Short.class, Short.class);
		classMap.put(Long.class, Long.class);
		classMap.put(Float.class, Float.class);
		classMap.put(Double.class, Double.class);
		classMap.put(Character.class, Character.class);
		classMap.put(Boolean.class, Boolean.class);
		classMap.put(Byte.class, Byte.class);
		classMap.put(String.class, String.class);
	}


	public Object[] getMethodParam(HttpServletRequest request, Class<?>[] paramsType, String[] actionParamsName)
	{
		Object[] params = new Object[actionParamsName.length];
		for (int i = 0; i < actionParamsName.length; i++)
		{
			Map<String, String[]> requestMap = request.getParameterMap();
			Iterator<Entry<String, String[]>> it = requestMap.entrySet().iterator();
			try
			{
				Object object = paramsType[i].newInstance();
				while (it.hasNext())
				{
					System.out.println(i);
					if (isBasicType(paramsType[i]))
					{
						Entry<String, String[]> entry = it.next();
						String value = "";
						for (String s : entry.getValue())
						{
							value += s;
						}
						if (entry.getKey().equals(actionParamsName[i]))
						{
							params[i] = basicType(paramsType[i], value);

						}
					} else
					{
						Field[] fields = paramsType[i].getDeclaredFields();
						Entry<String, String[]> entry = it.next();
						String paramName;
						String value = "";
						for (String s : entry.getValue())
						{
							value += s;
						}
						if (entry.getKey().indexOf(".") > 0 && entry.getKey().split("\\.")[0].equals(actionParamsName[i]))
						{
							for (Field field : fields)
							{
								if (field.getName().equals(entry.getKey().split("\\.")[1]))
								{
									paramName = entry.getKey().split("\\.")[1];
									String methodName = "set" + toFirstLetterUpperCase(paramName);
									paramsType[i].getMethod(methodName, field.getType()).invoke(object, value);
								}
							}
							params[i] = object;
						}
					}
				}
			} catch (InstantiationException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return params;
	}

	private boolean isBasicType(Class clazz)
	{
		if (clazz.equals(int.class) || clazz.equals(Integer.class))
		{
			return true;
		} else if (clazz.equals(short.class) || clazz.equals(Short.class))
		{
			return true;
		} else if (clazz.equals(long.class) || clazz.equals(Long.class))
		{
			return true;
		} else if (clazz.equals(float.class) || clazz.equals(Float.class))
		{
			return true;
		} else if (clazz.equals(double.class) || clazz.equals(Double.class))
		{
			return true;
		} else if (clazz.equals(char.class) || clazz.equals(Character.class))
		{
			return true;
		} else if (clazz.equals(boolean.class) || clazz.equals(Boolean.class))
		{
			return true;
		} else if (clazz.equals(byte.class) || clazz.equals(Byte.class))
		{
			return true;
		} else if (clazz.equals(String.class))
		{
			return true;
		} else
		{
			return false;
		}
	}
	/**
	 * 基础数据绑定
	 * @param class1
	 * @param value
	 * @return
	 */
	private Object basicType(Class<?> class1, String value)
	{
		if (isBasicType(class1))
		{
			Class<?> newClass = classMap.get(class1);
			if (newClass.equals(Integer.class))
			{
				return Integer.parseInt(value);
			} else if (newClass.equals(Short.class))
			{
				return Short.parseShort(value);
			} else if (newClass.equals(Long.class))
			{
				return Long.parseLong(value);
			} else if (newClass.equals(Float.class))
			{
				return Float.parseFloat(value);
			} else if (newClass.equals(Double.class))
			{
				return Double.parseDouble(value);
			} else if (newClass.equals(Character.class))
			{
				return value.toCharArray()[0];
			} else if (newClass.equals(Boolean.class))
			{
				return Boolean.parseBoolean(value);
			} else if (newClass.equals(Byte.class))
			{
				return Byte.parseByte(value);
			} else
			{
				return value;
			}
		} else if (class1.equals(java.util.Date.class))
		{
			try
			{
				if (value.indexOf(":") == -1)
				{
					return new SimpleDateFormat("yyyy-MM-dd").parse(value);
				} else
					return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
			} catch (Exception e)
			{
				e.printStackTrace();
				return null;
			}
		} else
		{
			return class1.cast(value);
		}
	}
	/**
	 * 转换String的第一个字母
	 * @param s
	 * @return
	 */
	public String toFirstLetterUpperCase(String s)
	{
		if (s.length() == 1)
		{
			return s.toUpperCase();
		} else if (s == null || s.length() == 0)
		{
			return "";
		} else
		{
			return s.substring(0, 1).toUpperCase() + s.substring(1);
		}
	}

}
